var EventEmitter = require('events').EventEmitter
import L from "leaflet"
import "leaflet/dist/leaflet.css"
import './leaflet.ChineseTmsProviders'
import 'leaflet.vectorgrid'
import axios from 'axios'
import HeatmapOverlay from 'heatmap.js/plugins/leaflet-heatmap'
import 'leaflet.markercluster'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
import * as mapv from 'mapv'

delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
    iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
    iconUrl: require('leaflet/dist/images/marker-icon.png'),
    shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})

export class LeafletMapClass extends EventEmitter {
    constructor(divId) {
        super()
        this._divId = divId
        this._map = null
        this._layerDict = {}
        this._clickSearchList = []
        this._currClickSearchList = []
        this._clickResLayer = null
        this._drawLayer = null
        this.createMap()
    }

    createMap = () => {
        this._map = L.map(this._divId, {
            center: [31.205815, 121.455017],
            zoom: 15,
            minZoom: 3,
            maxZoom: 18,
            //crs: L.CRS.EPSG3857, //默认3857
            attribution: "&copy; 高德地图"
        })
        this._layerDict['baseNormalLayer'] = L.tileLayer.chinaProvider('Geoq.Normal.Gray', {maxZoom: 18, minZoom: 5}).addTo(this._map)
        this._layerDict['baseSatelayer'] = L.tileLayer.chinaProvider("GaoDe.Satellite.Map", {maxZoom: 18, minZoom: 5})
        this._layerDict['basePurplishBluelayer'] = L.tileLayer.chinaProvider("Geoq.Normal.PurplishBlue", {
            maxZoom: 18,
            minZoom: 5
        })
        this._drawLayer = L.featureGroup().addTo(this._map);
        this._map.on('click', res => {
            if (this._clickResLayer) this._clickResLayer.clearLayers()
            this.getClickFeatrue(res.latlng)
        })

    }
    addWMSLayer = (opts) => {
        this._layerDict[opts.layerId] = L.tileLayer.wms(opts.root + '/wms', opts.layerParams)
        this.addToClickSearchList(opts)
    }
    addWFSLayer = (opts) => {
        this.requestWFSData(opts).then(
            res => {
                if (res.data.features.length !== 0) {
                    this._layerDict[opts.layerId] = L.geoJSON(res.data, opts.options)
                }
            }
        )
        this.addToClickSearchList(opts)
    }
    addMakerLayer = (opts) => {
        this.requestWFSData(opts).then(
            res => {
                if (res.data.features.length > 0) {
                    this._layerDict[opts.layerId] = L.markerClusterGroup({
                        spiderfyOnMaxZoom: false,
                        showCoverageOnHover: false,
                        zoomToBoundsOnClick: false
                    }).addTo(this._map)
                    res.data.features.forEach(
                        f => {
                            var c = f.geometry.coordinates
                            var title = f.properties[opts.idField]
                            var marker = L.marker(new L.LatLng(c[0][1], c[0][0]));
                            marker.bindPopup(title.toString())
                            this._layerDict[opts.layerId].addLayer(marker);
                        }
                    )
                }
            }
        )
    }
    addVectorTileLayer = (opts) => {
        var options = {
            rendererFactory: L.canvas.tile,
            tms: true,
            interactive: true,
            vectorTileLayerStyles: opts.vectorTileLayerStyles
        }
        this._layerDict[opts.layerId] = L.vectorGrid.protobuf(opts.url, options)
        this.addToClickSearchList(opts)
    }

    addHeatMapLayer = (opts) => {
        this._layerDict[opts.layerId] = new HeatmapOverlay(
            {
                "radius": 100,
                "maxOpacity": .8,
                "scaleRadius": false,
                "useLocalExtrema": false,
                latField: 'lat',
                lngField: 'lng',
                valueField: 'count'
            }
        )
        this._layerDict[opts.layerId].setData(opts.heatData)
    }

    addToClickSearchList = (opts) => {
        this._clickSearchList.push({
            root: opts.root,
            layerId: opts.layerId,
            idField: opts.idField,
            crs: opts.crs,
            added: false
        })
    }
    addMapvLayer = (opts) => {
        this._layerDict[opts.layerId] = mapv.leafletMapLayer(new mapv.DataSet(opts.dataList),
            opts.options)
    }
    addLayerToMap = (layerId) => {
        this._layerDict[layerId].addTo(this._map)
        console.log(this._layerDict[layerId])
        if (this._clickSearchList.filter(i => i.layerId === layerId).length > 0) {
            this._clickSearchList.filter(i => i.layerId === layerId)[0].added = true
        }
    }
    removeLayer = (layerId) => {
        this._map.removeLayer(this._layerDict[layerId])
        if (this._clickSearchList.filter(i => i.layerId === layerId).length > 0) {
            this._clickSearchList.filter(i => i.layerId === layerId)[0].added = false
        }
    }
    getLayerById = (layerId) => {
        return this._map.hasLayer(this._layerDict[layerId]) ? this._layerDict[layerId] : null
    }
    clearDrawLayer = () =>{
        this._drawLayer.clearLayers()
        this._map.off('click')
        this._map.off('dblclick')
        this._map.doubleClickZoom.enable()
    }
    getClickFeatrue = (pt) => {
        if (this._clickSearchList.length === 0) return
		if(document.getElementById("popup")) document.getElementById("popup").remove()
        var content = '<a id="popup" style="text-decoration: underline;cursor: pointer;">'
        this._clickSearchList.forEach(
            l => {
                if (l.added) {
                    var cpt
                    if (l.crs === 'EPSG:4326') cpt = L.CRS.EPSG4326.project(pt)
                    if (l.crs === 'EPSG:3857') cpt = L.CRS.EPSG3857.project(pt)
                    l.cql_filter = 'INTERSECTS(geom,POINT(' + cpt.x + ' ' + cpt.y + '))'
                    this.requestWFSData(l).then(
                        res => {
                            if (res.data.features.length !== 0) {
                                var geoObj = L.geoJSON(res.data)
                                content = content + res.data.features[0].properties[l.idField] + '</a>'
                                this._clickResLayer = geoObj.addTo(this._map);
                                geoObj.bindPopup(content).openPopup()
								this.emit('clickEnd',res.data.features[0].properties)
								
                            }
                        }
                    )
                }
            }
        )
    }
    requestWFSData = (opts) => {
        return new Promise(
            (resolve, reject) => {
                var urlString = opts.root + '/wfs'
                var param = {
                    service: 'WFS',
                    version: '1.0.0',
                    request: 'GetFeature',
                    typeName: opts.layerId,
                    outputFormat: 'application/json',
                    maxFeatures: 3200,
                    srsName: 'EPSG:4326',
                }
                if (opts.cql_filter) param.CQL_FILTER = opts.cql_filter
                axios.get(urlString + L.Util.getParamString(param, urlString)).then(
                    res => {
                        if (res.data) {
                            resolve(res)
                        } else {
                            reject('请求wfs错误')
                        }
                    }
                )
            }
        )
    }


}
